package com.pactera.miyuangroup.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 描述：redis 操作类
 * </p>
 *
 * @author wangwu
 * @date 2017年11月21日 下午2:56:51
 */
@Component
public class RedisOperation {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * redis 保存永久数据
     *
     * @param key
     * @param value
     */
    public <T> void set(String key, T value) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, value);
    }

    /**
     * redis 保存时效性数据
     *
     * @param key
     * @param time  有效期 （单位：秒）
     * @param value
     */
    public <T> void set(String key, Long time, T value) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, value, time, TimeUnit.SECONDS);
    }

    /**
     * 获取redis 数据
     *
     * @param key
     * @param t
     * @return
     */
    public <T> T get(String key, Class<T> t) {
        return (T) redisTemplate.opsForValue().get(key);
    }

    public <T> T get(String key, Class<T> t, T def) {
        if (isExists(key)) {
            return (T) redisTemplate.opsForValue().get(key);
        }
        return def;
    }

    /*********** redis集合操作 ***************/

    /**
     * 在名称为key的list头添加一个值为value的 元素
     *
     * @param key
     * @param value
     */
    public <T> void setListByHead(String key, T value) {
        ListOperations listOperations = redisTemplate.opsForList();
        listOperations.leftPush(key, value);
    }

    /**
     * 在名称为key的list尾添加一个值为value的元素
     *
     * @param key
     * @param value
     */
    public <T> void setListByTail(String key, T value) {
        ListOperations listOperations = redisTemplate.opsForList();
        listOperations.rightPush(key, value);
    }

    /**
     * 删除重复数据<br/>
     * 删除所有key的list中值为value的元素
     *
     * @param key
     * @param value
     */
    public <T> long removeRepeatAll(String key, T value) {
        ListOperations listOperations = redisTemplate.opsForList();
        return listOperations.remove(key, 0, value);
    }

    /**
     * 返回并删除名称为key的list中的首元素
     *
     * @param key
     * @return
     */
    public <T> T getListByHead(String key, Class<T> t) {
        return (T) redisTemplate.opsForList().leftPop(key);
    }

    public <T> T getListByHead(String key, Class<T> t, T def) {
        if (isExists(key)) {
            return (T) redisTemplate.opsForList().leftPop(key);
        }
        return def;
    }

    /**
     * 返回并删除名称为key的list中的尾元素
     *
     * @param key
     * @return
     */
    public <T> T getListByTail(String key, Class<T> t) {
        return (T) redisTemplate.opsForList().rightPop(key);
    }

    /**
     * 查询key集合中所有数据
     *
     * @param <T>
     * @param key
     * @return
     */
    public <T> List<T> getListAll(String key, Class<T> t) {
        return (List<T>) redisTemplate.opsForList().range(key, 0, -1);
    }

    /**
     * 查询key集合中数据个数
     *
     * @param <T>
     * @param key
     * @return
     */
    public long getListSize(String key) {
        return redisTemplate.opsForList().size(key);
    }

    /***** 对Hash操作的命令 **********/

    /**
     * 设置Hash值value
     *
     * @param key
     * @param hkey
     * @param value
     */
    public <T> void setHash(String key, String hkey, T value) {
        redisTemplate.opsForHash().put(key, hkey, value);
    }

    /**
     * 获取Hash值value
     *
     * @param key
     * @param hkey
     * @param t
     * @return
     */
    public <T> T getHash(String key, String hkey, Class<T> t) {
        return (T) redisTemplate.opsForHash().get(key, hkey);
    }

    public <T> T getHash(String key, String hkey, Class<T> t, T def) {
        if (!isExists(key)) {
            return def;
        }
        if (!isExistsHasKey(key, hkey)) {
            return def;
        }
        return (T) redisTemplate.opsForHash().get(key, hkey);

    }

    /**
     * 删除名称为key的hash中键为hkey的域
     *
     * @param key
     * @param hkey
     * @return
     */
    public long delHashByHKey(String key, String hkey) {
        return redisTemplate.opsForHash().delete(key, hkey);
    }

    /**
     * 返回名称为key的hash中所有的键其对应的value
     *
     * @param key
     * @param hkey
     * @param t
     * @return
     */
    public <T> List<T> getHashAll(String key, Class<T> t) {
        return (List<T>) redisTemplate.opsForHash().values(key);
    }

    public <T> Map<String, T> entries(String key, Class<T> t) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 返回名称为key的hash中所有的键其对应的value
     *
     * @param key
     * @param hkey
     * @param t
     * @return
     */
    public Map getHashAll(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 删除对应key所有的数据
     *
     * @param key
     */
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 验证对应key是否存在
     *
     * @param key
     */
    public boolean isExists(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 验证对应hashKey是否存在
     *
     * @param key
     * @param hashKey
     */
    public boolean isExistsHasKey(String key, Object hashKey) {
        if (!isExists(key)) {
            return false;
        }
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }
}
